#include "base/logging.h"
#include "ImCallCenterService_types.h"
#include "ImCallCenterService.h"

#include "base/get_local_ip.h"
#include "melon/service/service_arch.h"
#include "melon/service/base_service_impl.h"
#include "redis_executor/simple_redis_locator.h"

#include "dispatch_message_task.h"
#include "shop_waiter_map.h"
#include "redis_adapter.h"

namespace imserver {

RedisAdapter * g_redis_adapter;

using apache::thrift::concurrency::Runnable;

class ImCallCenterServiceHandler : public ImCallCenterServiceIf, public melon::service::BaseServiceImpl {
 public:
  ImCallCenterServiceHandler() {
  }
  virtual void DispatchMessage(const ImMessage& message) {
    LOG_INFO("DispatchMessage sender=" << message.sender << " receiver=" << message.receiver);
    using apache::thrift::concurrency::Runnable;
    GetThreadManager()->add(boost::shared_ptr<Runnable>(new DispatchMessageTask(message)));
  }
  virtual int64_t GetLinkedShop(const int64_t waiter, const int64_t customer) {
    int64_t shop = g_redis_adapter->GetLinkedShop(waiter, customer);
    LOG_INFO("GetLinkedShop waiter=" << waiter << " customer=" << customer << " shop=" << shop);
    return shop;
  }
};

}
int main(int argc, char **argv) {
  char * conf_file = "../conf/im_call_center_service.conf";
  char opt;
  while ((opt = getopt(argc, argv, "c:")) != -1) {
    switch (opt) {
    case 'c':
      conf_file = optarg;
      break;
    default:
      std::cerr << "Unknown option " << optopt << std::endl;
      return 1;
    }
  }

  ConfigReader cfg(conf_file);
  if (!cfg) {
    std::cerr << "Config file " << conf_file << " read error!" << std::endl;
    return 1;
  }

  LOG_INIT(cfg.Get("log4cplus", "file"), cfg.Get("log4cplus", "level"));

  int port = cfg.GetWithType<int>("im_call_center_service", "port", 9089);
  LOG_INFO("listens on port " << port);

  using namespace imserver;
  g_redis_adapter = new RedisAdapter(new FixedLocator(cfg.Get("redis", "server_list")));

#if 1
  ShopWaiterMap::Instance().Reload();
  melon::service::ThriftService<ImCallCenterServiceHandler, ImCallCenterServiceProcessor> service;
  service.StartRegister("/im/im_call_center_service", "1.0", 0, base::GetLocalIp(), port, 1);
  service.Start(port);
#endif

#if 0
  ShopWaiterMap& o = ShopWaiterMap::Instance();
  o.Reload();
  int64_t mapped_sender = 0;
  int64_t mapped_receiver = 0;
  for(int i = 0; i < 100; ++i) {
    // 来自waiter的消息
    o.MapSenderReceiver(288297970, 10001, &mapped_sender, &mapped_receiver);
    std::cout << "mapped_sender=" << mapped_sender << std::endl;

    // 来自waiter的消息
    o.MapSenderReceiver(101, 10001, &mapped_sender, &mapped_receiver);
    std::cout << "mapped_sender=" << mapped_sender << std::endl;

    // 来自waiter的消息
    o.MapSenderReceiver(201, 10001, &mapped_sender, &mapped_receiver);
    std::cout << "mapped_sender=" << mapped_sender << std::endl;

    // 来自waiter的消息
    o.MapSenderReceiver(301, 10001, &mapped_sender, &mapped_receiver);
    std::cout << "mapped_sender=" << mapped_sender << std::endl;
  }
#endif

#if 0
  ShopWaiterMap& o = ShopWaiterMap::Instance();
  o.Reload();
  int64_t mapped_sender = 0;
  int64_t mapped_receiver = 0;
  for(int i = 0; i < 100000000; ++i) {
    o.MapSenderReceiver(100001, 127646892, &mapped_sender, &mapped_receiver);
    std::cout << "mapped_sender=" << mapped_sender << std::endl;
    std::cout << "mapped_receiver=" << mapped_receiver << std::endl;
  }
#endif

#if 0
  ShopWaiterMap& o = ShopWaiterMap::Instance();
  o.Reload();

  ImCallCenterServiceHandler h;
  ImMessage message;
  message.sender = message.receiver;
  message.receiver = message.sender;
  message.timestamp = time(NULL);
  message.body = "呼叫中心测试消息";

  h.DispatchMessage(message);
#endif
  return 0;
}

